package controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import service.SaveItems;

import model.ClassDoublePojo;
import model.ClassPojo;
import model.PropPojo;

import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.NsIterator;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

import dao.ClassDao;
import dao.ClassDefDao;
import dao.PropDao;

public class MultiPurposeParser {

	public static void main(String[] args) {

//		String file = "http://www.informatik.uni-ulm.de/ki/Liebig/owl/SUMO-LiteTB.rdf";
//		String file = "http://inferenceweb.stanford.edu/2004/07/iw.owl";
//		String file = "http://www.mindswap.org/~glapizco/technical.owl";
		String file = "http://www.aktors.org/ontology/portal";
//		String file = "http://auscope-services-test.arrc.csiro.au/nvcl-scalars.rdf";
//		String file = "http://auscope-services-test.arrc.csiro.au/nvcl.rdf";
		
		
		// OntModelSpec s = new OntModelSpec( OntModelSpec.OWL_MEM );
		OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		model.read(file);
		OntClass c = model.getOntClass(file);

		MultiPurposeParser mpp = new MultiPurposeParser();
		mpp.saveTriples(model);
		if(c!=null){
		 mpp.getSubClasses(c);
		}

		mpp.getAllClasses(model);
		mpp.getAllClassProperties(model);
	}

	public void saveTriples(Model m) {

		// get the triples
		// save the triple
		
		StmtIterator itr = m.listStatements();
		while(itr.hasNext()){
			Statement stmt = itr.nextStatement();
			Resource sub = stmt.getSubject();
			Property pre = stmt.getPredicate();
			RDFNode obj = stmt.getObject();
			
	
			SaveItems save = new SaveItems();
			save.saveTriple(sub, pre, obj);
		}

	}

	public void getAllClasses(OntModel model) {

		ExtendedIterator<OntClass> itr = model.listClasses();

		while (itr.hasNext()) {
			OntClass c = itr.next();
			if (c.getURI() != null) {
//System.out.println(c.getURI() + " - " + c.getLocalName());
				SaveItems save = new SaveItems();
				save.saveClass(c);
			}
		}
	}

	public void getAllClassProperties(OntModel model) {

		HashMap<OntResource, ArrayList<OntProperty>> cpList = new HashMap<OntResource, ArrayList<OntProperty>>();
			// create a hashmap of a resource and its associated properties

		ExtendedIterator<OntProperty> itr = model.listAllOntProperties();		// get a list of all the properties
		while (itr.hasNext()) {
			OntProperty p = itr.next();
			OntResource d = p.getDomain();		// get the domain for a property - class to which this property can be belong
			OntResource r = p.getRange();		// get the range for a property - class from which the "object" can be in a triple ??? what the
			try {
				if (cpList.containsKey(d)) {	// if the HashMap has a domain class d
					ArrayList<OntProperty> plist = cpList.get(d);
					plist.add(p);				// add the property to the list of proeprties for that domain
					cpList.put(d, plist);		// add the new plist into the cpList (master list)
				} else {
					ArrayList<OntProperty> l = new ArrayList<OntProperty>();
					l.add(p);					// otherwise first create a new ArrayList to contain the proeprties
					cpList.put(d, l);
					}
// System.out.println(d.getURI()+ " - "+ p.getURI());
				} catch (NullPointerException e) {
			}
		}
		// Iterate through the HashMap and display all classes and properties

		Set<OntResource> classes = cpList.keySet();				// now we persist to the DB (and print to screen)
		Iterator<OntResource> hitr = classes.iterator();
		while (hitr.hasNext()) {
			OntResource cla = hitr.next();						// iterating over OntResource objects
			if (cla != null) {					// 
// System.out.println("C: " + cla.getURI() + " - "+ cla.getLocalName());		//	
				ArrayList<OntProperty> pList = cpList.get(cla);								// get the list of properties for a class
				Iterator<OntProperty> propItr = pList.iterator();							// create an iterator over the list of properties
				while (propItr.hasNext()) {
					OntProperty prop = propItr.next();				// get the next property in the iterator
					if (prop != null) {								// if there is a property
						System.out.println("  P: " + prop.getURI() + " "+ prop.getLocalName());
	
						SaveItems save = new SaveItems();
						save.saveClassDefn(cla, prop);		// this does all the checking for duplicates etc and saves to the DB
					}
				}
			}
		}
	}

	public void getSubClasses(OntClass cla) {
		
		// need to get a list of all subclasses for all the classes
		ExtendedIterator<OntClass> itr = cla.listSubClasses();
		while (itr.hasNext()) {
			OntClass subCla = itr.next();
			System.out.println(cla.getURI());
			SaveItems save = new SaveItems();
			save.saveSubClass(cla, subCla);
		}
	}

//	public void getSubjects(OntModel model) {
//		ResIterator itr = model.listSubjects();
//		while (itr.hasNext()) {
//			Resource r = itr.next();
////			System.out.println(r.toString());
//		}
//	}
//
//	public void getProperties(OntModel model, OntClass c) {
//
//		StmtIterator itr = c.listProperties();
//		try {
//			while (itr.hasNext()) {
//				Statement r = itr.nextStatement();
////				System.out.println(r.toString());
//			}
//		} catch (NullPointerException e) {
////			System.out.println("There are no properties associated with the class");
//		}
//	}
}
